#include "io.hpp"
#include "tlv.h"
#include <my_header.h>


namespace rocket 
{
io::io(int fd)
:_fd(fd)
{
    
}
io::~io()
{

}
int io::read_peek(char *buff,int length)
{
    int ret=recv(_fd, buff, length, MSG_PEEK);
    if(ret<0)
    {
        perror("recv");
    }
    return ret;
}
int io::read_n(char *buff,int length)
{
    int len=length;
    char *p=buff;
    while(len>0) 
    {
        int ret=recv(_fd, p, len, 0);
        if(ret<0)
        {
            perror("recv");
            return ret;
        }
        len-=ret;
        p+=ret;
    }
    return length-len;
}

int io::write_n(char *buff,int length)
{
    
    int len=length;
    char *p=buff;
    while(len>0) 
    {
        int ret=send(_fd, p, len,0);
        if(ret<0)
        {
            perror("send");
            return ret;
        }
        len-=ret;
        p+=ret;
    }
    return length-len;

}

int io::read_line(char *buff, int max_length)
{
    
    int len=max_length-1;
    char *p=buff;
    while(len>0) 
    {
        int ret=read_peek(p,  len);
        if(ret<0)
        {
            perror("read_peek");
            return ret;
        }
        for(int i=0;i<ret;++i)
        { 
            if(p[i]=='\n')
            {
                ret=recv(_fd, p, i+1, 0);
                if(ret<0)
                {
                    perror("recv");
                    return ret;
                }     
                p[i+1]='\0';
                return strlen(buff);   
            }
        }       
        ret=recv(_fd, p, ret, 0);
        if(ret<0)
        {
            perror("recv");
            return ret;
        }
        len-=ret;
        p+=ret;
    }
    buff[max_length-1]='\0';
    return max_length-1;
}

//用来读取tlv格式数据，返回packet类型
int io::read_packet(packet &object)
{
    char buff[1024]={0};
    //接收tlv数据包的type和length
    int ret1=read_n(buff, 8);
    //解析tlv数据包的type和length
    int type=*(int *)buff;
    int length=*(int *)(buff+4);
    memset(buff, 0,ret1);
    //接收tlv数据包的value
    int ret2=read_n(buff,length);
    //构建一个tlv对象
    tlv temp(type,length,buff);
    //用tlv对象为packet赋值
    object.set_type(temp.get_type());
    object.set_length(temp.get_length());
    object.set_data(temp.get_data());
    //返回接收到总字节数
    return ret1+ret2;
}

}